/*
 * LocationHandler.cpp
 *
 *  Created on: Jan 29, 2015
 *      Author: wasp
 */

#include "applicationui.hpp"
#include "LocationHandler.hpp"
#include "location/Location.hpp"
#include "tracking/Tracker.hpp"
#include "location/Route.hpp"
#include "security/System.hpp"
#include <bb/platform/geo/GeoLocation>
#include <bb/cascades/Application>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/maps/MapView>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QDebug>
#include <bb/data/DataAccessError>
#include <bb/data/JsonDataAccess>
/*



#include <bb/platform/geo/Point>

#include <bb/platform/geo/Marker>
#include <bb/platform/geo/Coordinate>
#include <bb/platform/geo/Polyline>
#include <bb/platform/geo/GeoPolyline>
#include <bb/cascades/places/SelectedPlace>

#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSettings>
#include <QSslConfiguration>
#include <bb/data/JsonDataAccess>
using namespace bb::data;
 */

namespace de
{
    namespace heimweghelden
    {
        LocationHandler::LocationHandler(QObject* parent) :
            QObject(parent),
            app(reinterpret_cast<ApplicationUI*>(parent)),
            location(new de::heimweghelden::location::Location(this)),
            tracker(new de::heimweghelden::tracking::Tracker(this))
        {
            estimatedDuration = 0;
            mapView = 0;
            reply = 0;
        }

        LocationHandler::~LocationHandler(){}

        bool LocationHandler::setMap(bb::cascades::maps::MapView* map) {
            if (mapView != 0) {
                return false;
            }
            mapView = map;
            location->setMap(map);

            return true;
        }

        bb::cascades::maps::MapView* LocationHandler::getMap() {
            return mapView == 0 ? NULL : mapView;
        }

        void LocationHandler::updateDeviceLocation(double lat, double lon) {
            location->updateDevice(lat, lon);
        }

        void LocationHandler::updateDestinationLocation(double lat, double lon, QString destcription) {
            location->setRoute(lat, lon, destcription);
            QObject* v = bb::cascades::Application::instance()->scene()->findChild<QObject*>(QString("mapPage"));
            v->setProperty("status", 1);

            // get route information
            QNetworkRequest request = QNetworkRequest();
            QString qurls;
            qurls
                .append("https://maps.googleapis.com/maps/api/directions/json?mode=walking&origin=")
                .append(QString::number(location->current()->latitude()))
                .append(",")
                .append(QString::number(location->current()->longitude()))
                .append("&destination=")
                .append(QString::number(lat))
                .append(",")
                .append(QString::number(lon))
                .append("&sensor=true");
            request.setUrl(
                    QUrl(qurls)
            );
            reply = app->networkmanager()->get(request);
            if (reply->isFinished()) {
                gmapRouteRequestFinished();
            } else {
                reply->connect(reply, SIGNAL(finished()), this, SLOT(gmapRouteRequestFinished()));
            }
        }
        void LocationHandler::resetDestinationLocation() {
            location->resetRoute();
            QObject* v = bb::cascades::Application::instance()->scene()->findChild<QObject*>(QString("mapPage"));
            v->setProperty("status", 0);
            v->setProperty("followMe", true);
        }
        void LocationHandler::onResetRoute() {
            location->resetRoute();
        }
        void LocationHandler::onRouteStart() {
            dialog = new bb::system::SystemDialog("","",this);
            dialog->setActivityIndicatorVisible(true);
            dialog->setTitle(tr("Please wait"));
            dialog->setBody(tr("Starting route..."));
            dialog->show();
            connect(location->route(), SIGNAL(routeStarted()),
                    this, SLOT(onRouteStarted()));
            /*connect(
                    location->route(),
                    SIGNAL(onTimeLapsed(int)),
                    this,
                    SLOT(onLapsedTimeChanged(int))
            );
            connect(
                    location->route(),
                    SIGNAL(exceeded(int, int, double, double)),
                    tracker,
                    SLOT(exceeded(int, int, double, double))
            );
            //connect(location->route(), SIGNAL(arrived()), tracker, SLOT(arrived()));
            tracker->start(location->route());
            */
            location->route()->start();
        }
        void LocationHandler::onRouteStarted() {
            dialog->deleteLater();
        }
        void LocationHandler::onLapsedTimeChanged(int estimatedDuration) {
            onRouteSetDuration(estimatedDuration);
        }

        void LocationHandler::onRouteSetDuration(int duration) {
            qDebug() << "LocationHandler::onRouteSetDuration" << duration;
            QObject* v = bb::cascades::Application::instance()->scene()->findChild<QObject*>(QString("mapPage"));
            v->setProperty("duration", duration);
            location->route()->updateEstimatedDuration(duration);
            estimatedDuration = duration;
        }
        int LocationHandler::onRouteUpdateHelden(QString number, bool active) {
            return location->route()->updateHelden(number, active);
        }
        void LocationHandler::gmapRouteRequestFinished() {
            QString response;
                if (reply) {
                    if (reply->error() == QNetworkReply::NoError) {
                        int available = reply->bytesAvailable();
                        if (available > 0) {
                            QByteArray buffer(reply->readAll());
                            response = QString::fromUtf8(buffer);
                        }
                    } else {
                        response = tr("Error: %1 status: %2").arg(reply->errorString(), reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString());
                        qDebug() << response;
                    }

                    reply->deleteLater();
                } else {
                    reply = NULL;
                    return;
                }

                if (response.trimmed().isEmpty()) {
                    response = tr("Unable to retrieve post response");
                    // TODO: meldung
                    reply = NULL;
                    return;
                }

                bb::data::JsonDataAccess jda;
                QVariant qtData = jda.loadFromBuffer(response);
                if (jda.hasError()) {
                    bb::data::DataAccessError err = jda.error();
                    QString errorMsg = tr("Error converting JSON data: %1").arg(err.errorMessage());
                    qDebug() << errorMsg;
                    //TODO: fehlermeldung
                } else {
                    QVariant t;
                    QVariantMap map = qtData.value<QVariantMap>();
                    t = map.value("routes");
                    t = t.value<QVariantList>().value(0);
                    QVariantMap route = t.value<QVariantMap>();
                    QVariantMap leg = route.value("legs").value<QVariantList>().at(0).value<QVariantMap>();
                    QVariantMap distance = leg.value("distance").value<QVariantMap>();
                    QVariantMap duration = leg.value("duration").value<QVariantMap>();
                    QVariantMap startRoute = leg.value("start_location").value<QVariantMap>();

                    int durationSeconds = duration.value("value").value<long>();
                    onRouteSetDuration(durationSeconds);
                    QObject* v = bb::cascades::Application::instance()->scene()->findChild<QObject*>(QString("mapPage"));
                    v->setProperty("followMe", false);
                }
                reply = NULL;
        }
    } /* namespace heimweghelden */
} /* namespace de */
